package com.zb.service.impl;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.collection.CollectionUtil;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.Assert;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.zb.constant.WorkConstant;
import com.zb.entity.*;
import com.zb.excel.converter.WorkConverter;
import com.zb.extend.WorkFeeDetailExtend;
import com.zb.extend.WorkNetworkExtend;
import com.zb.list.WorkFeeLogListVo;
import com.zb.mapper.ZjWorkFeeMapper;
import com.zb.result.PageUtil;
import com.zb.service.*;
import com.zb.utils.ZbOrderNoUtil;
import com.zb.vo.*;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.stream.Collectors;

/**
 * <p>
 * 工单费用表 服务实现类
 * </p>
 *
 * @author WEN
 * @since 2023-10-25
 */
@Service
public class ZjWorkFeeServiceImpl extends ServiceImpl<ZjWorkFeeMapper, ZjWorkFee> implements ZjWorkFeeService {
    @Resource
    private ZjWorkFeeMapper workFeeMapper;
    @Resource
    private ZjWorkFeeDetailService workFeeDetailService;

    // 根据工单ID获取工单详情的服务项目列表
    @Override
    public Map<String, Object> getOrderDetailFeeProjectList(Long workId, PageUtil pageUtil) {
        PageUtil.setPageLimit(pageUtil);
        List<ZjWorkFee> workFeeList = workFeeMapper.getOrderDetailFeeProjectList(workId, pageUtil);
        List<WorkFeeDetailExtend> feeDetailExtends = workFeeDetailService.getByWorkFeedIds(workFeeList.stream().map(ZjWorkFee::getId).toList());

        List<OrderDetailFeeProjectVo> voList = workFeeList.stream().map(fee -> {
            OrderDetailFeeProjectVo vo = new OrderDetailFeeProjectVo();
            BeanUtil.copyProperties(fee, vo);
            vo.setFeeNo(fee.getCode());
            vo.setCreateTime(fee.getGmtCreate());
            vo.setUpdateTime(fee.getGmtUpdate());
            List<WorkFeeDetailExtend> extendList = feeDetailExtends.stream().filter(f -> Objects.equals(f.getWorkFeeId(), fee.getId())).toList();
            vo.setSettlementType(extendList.stream().map(e -> {
                return WorkConverter.orderFeeOrOrderSpareSettlementTypeConverter(e.getType());
            }).distinct().collect(Collectors.joining("、")));
            vo.setFeeProject(extendList.stream().map(WorkFeeDetailExtend::getName).distinct().collect(Collectors.joining("、")));
            vo.setTotalPrice(extendList.stream().map(feeDetail -> {
                return feeDetail.getPrice().multiply(new BigDecimal(feeDetail.getQty()));
            }).reduce(new BigDecimal("0.00"), BigDecimal::add));
            vo.setPayNetworkTotalPrice(extendList.stream().map(feeDetail -> {
                return feeDetail.getPayNetworkPrice().multiply(new BigDecimal(feeDetail.getQty()));
            }).reduce(new BigDecimal("0.00"), BigDecimal::add));
            vo.setReceiveFactoryTotalPrice(extendList.stream().map(feeDetail -> {
                return feeDetail.getReceiveFactoryPrice().multiply(new BigDecimal(feeDetail.getQty()));
            }).reduce(new BigDecimal("0.00"), BigDecimal::add));
            vo.setSurePrice(extendList.stream().allMatch(f -> f.getSurePriceStatus() == 2));
            return vo;
        }).toList();
        return PageUtil.pageList(pageUtil.getPage(), pageUtil.getLimit(), workFeeMapper.getOrderDetailFeeProjectListCount(workId), voList);
    }

    // 获取工单服务费用项目列表
    @Override
    public List<ZjWorkFee> getList(Long custAccId, OrderFeeListSelectVo selectVo) {
        return workFeeMapper.getList(custAccId, selectVo);
    }

    // 获取工单服务费用项目列表总记录数
    @Override
    public long getListCount(Long custAccId, OrderFeeListSelectVo selectVo) {
        return workFeeMapper.getListCount(custAccId, selectVo);
    }

    // 根据工单服务费用项目ID获取工单服务费用项目详情
    @Override
    public OrderFeeDetailVo getOrderFeeDetail(Long id) {
        ZjWorkFee fee = this.getById(id);
        Assert.isTrue(null != fee, "服务费用项目ID参数["+ id +"]的服务项目的数据不存在");

        OrderFeeDetailVo vo = new OrderFeeDetailVo();
        BeanUtil.copyProperties(fee, vo);
        vo.setFeeNo(fee.getCode());
        vo.setCreateTime(fee.getGmtCreate());
        vo.setUpdateTime(fee.getGmtUpdate());

        List<WorkFeeDetailExtend> feeDetailExtends = workFeeDetailService.getByWorkFeedId(id);
        vo.setSettlementType(feeDetailExtends.stream().map(e -> {
            return WorkConverter.orderFeeOrOrderSpareSettlementTypeConverter(e.getType());
        }).distinct().collect(Collectors.joining("、")));
        vo.setSurePrice(feeDetailExtends.stream().allMatch(f -> f.getSurePriceStatus() == 2));
        BigDecimal receivePrice = feeDetailExtends.stream().filter(f -> f.getType() == 1 || f.getType() == 3).map(WorkFeeDetailExtend::getPrice).reduce(new BigDecimal("0.00"), BigDecimal::add);
        BigDecimal payPrice = feeDetailExtends.stream().filter(f -> f.getType() == 2 || f.getType() == 4).map(WorkFeeDetailExtend::getPrice).reduce(new BigDecimal("0.00"), BigDecimal::add);
        vo.setTotalPrice(receivePrice.subtract(payPrice));
        return vo;
    }

    // 根据服务商ID获取与工单费用关联的服务商ID
    @Override
    public List<Long> getRelationByNetworkIds(List<Long> networkIds) {
        if (CollectionUtil.isEmpty(networkIds)) {
            return new ArrayList<>();
        }
        QueryWrapper<ZjWorkFee> wrapper = new QueryWrapper<>();
        wrapper.select("network_id");
        wrapper.in("network_id", networkIds);
        return this.list(wrapper).stream().map(ZjWorkFee::getNetworkId).distinct().toList();
    }

    // 获取服务商详情之工单费用列表
    @Override
    public Map<String, Object> getNetworkDetailOrderFeeList(Long networkId, PageUtil pageUtil) {
        PageUtil.setPageLimit(pageUtil);
        long count = workFeeMapper.getNetworkDetailOrderFeeListCount(networkId);
        if (count <= 0) {
            return PageUtil.pageList(pageUtil.getPage(), pageUtil.getLimit(), count, new ArrayList<>());
        }
        List<ZjWorkFee> workFeeList = workFeeMapper.getNetworkDetailOrderFeeList(networkId, pageUtil);
        return PageUtil.pageList(pageUtil.getPage(), pageUtil.getLimit(), count, getFeeListVo(workFeeList));
    }

    // 获取商家详情之工单费用列表总记录数
    @Override
    public long getFactoryDetailOrderFeeListCount(Long factoryId) {
        return workFeeMapper.getFactoryDetailOrderFeeListCount(factoryId);
    }

    // 获取商家详情之工单费用列表
    @Override
    public Map<String, Object> getFactoryDetailOrderFeeList(Long factoryId, PageUtil pageUtil) {
        PageUtil.setPageLimit(pageUtil);
        long count = getFactoryDetailOrderFeeListCount(factoryId);
        if (count <= 0) {
            return PageUtil.pageList(pageUtil.getPage(), pageUtil.getLimit(),count, new ArrayList<>());
        }
        List<ZjWorkFee> workFeeList = workFeeMapper.getFactoryDetailOrderFeeList(factoryId, pageUtil);
        return PageUtil.pageList(pageUtil.getPage(), pageUtil.getLimit(), count, getFeeListVo(workFeeList));
    }

    private List<OrderFeeListVo> getFeeListVo(List<ZjWorkFee> workFeeList) {
        List<WorkFeeDetailExtend> feeDetailExtends = workFeeDetailService.getByWorkFeedIds(workFeeList.stream().map(ZjWorkFee::getId).toList());
        return workFeeList.stream().map(fee -> {
            OrderFeeListVo vo = new OrderFeeListVo();
            BeanUtil.copyProperties(fee, vo);
            vo.setFeeNo(fee.getCode());
            vo.setApplyEmp("【" + (fee.getApplyEmpType() == 1? "系统客服" : fee.getApplyEmpType() == 2? "服务商移动端" : "第三方系统") + "】" + fee.getApplyEmp());
            vo.setCreateTime(fee.getGmtCreate());
            vo.setUpdateTime(fee.getGmtUpdate());
            List<WorkFeeDetailExtend> extendList = feeDetailExtends.stream().filter(f -> Objects.equals(f.getWorkFeeId(), fee.getId())).toList();
            vo.setSettlementType(extendList.stream().map(e -> {
                return WorkConverter.orderFeeOrOrderSpareSettlementTypeConverter(e.getType());
            }).distinct().collect(Collectors.joining("、")));
            vo.setFeeProject(extendList.stream().map(WorkFeeDetailExtend::getName).distinct().collect(Collectors.joining("、")));
            vo.setTotalPrice(extendList.stream().filter(f -> f.getStatus() == 2).map(feeDetail -> {
                return feeDetail.getPrice().multiply(new BigDecimal(feeDetail.getQty()));
            }).reduce(new BigDecimal("0.00"), BigDecimal::add));
            vo.setPayNetworkTotalPrice(extendList.stream().filter(f -> f.getStatus() == 2).map(feeDetail -> {
                return feeDetail.getPayNetworkPrice().multiply(new BigDecimal(feeDetail.getQty()));
            }).reduce(new BigDecimal("0.00"), BigDecimal::add));
            vo.setReceiveFactoryTotalPrice(extendList.stream().filter(f -> f.getStatus() == 2).map(feeDetail -> {
                return feeDetail.getReceiveFactoryPrice().multiply(new BigDecimal(feeDetail.getQty()));
            }).reduce(new BigDecimal("0.00"), BigDecimal::add));
            vo.setSurePrice(extendList.stream().allMatch(f -> f.getSurePriceStatus() == 2));
            return vo;
        }).toList();
    }


    // 根据工单ID与单号查询存在的费用
    @Override
    public ZjWorkFee getByWorkIdAndCode(Long workId, String orderNo) {
        return workFeeMapper.getByWorkIdAndCode(workId, orderNo);
    }

}
